
<template>
  <div>
    <el-table :data="filterTableData" style="width: 100%">
      <el-table-column label="Name">
        <template #default="scope">
          <el-tooltip :content="scope.row.id">
            <el-button size="small" @click="highlight(scope.row)" type="primary">{{ scope.row.name }}
            </el-button>
          </el-tooltip>
        </template>
      </el-table-column>
      <el-table-column label="Direction" prop="type" />
      <el-table-column align="right">
        <template #header>
          <el-input v-model="search" size="small" placeholder="Type to search" />
        </template>
        <template #default="scope">
          <el-button size="small" @click="handleDelete(scope.$index, scope.row)" type="danger">
            <el-icon>
              <delete />
            </el-icon>
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-row>
      <el-button @click="portSelectShow = true">
        <el-icon>
          <plus />
        </el-icon>
      </el-button>
    </el-row>
    <el-dialog v-model="portSelectShow">
      <el-row>
        <el-col span="12">
          <el-select v-model="selectedPortID">
            <el-option :key="portToEndpointUUID(port)"
              :label="statusMgr.getNode(port.nodeID).type + ':' + port.endpointID" :value="portToEndpointUUID(port)"
              :disabled="endpointOccupied(portToEndpointUUID(port))" v-for="port in allEndpoints"></el-option>
          </el-select>
        </el-col>
        <el-col span="8">
          <el-input v-model="routePortName"></el-input>
        </el-col>
      </el-row>
      <template #footer>
        <el-button @click="portSelected">Add as {{ endpointDirection(selectedPortID) }}</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import { Plus, Delete } from "@element-plus/icons-vue";
import {
  computed,
  reactive,
  ref,
  defineProps,
  defineExpose,
} from "vue";
import { RoutePort, Port, RouteSettings } from "../flowchart/models";
import { emitHighlightPort } from "@/components/EventBus";
import { portToEndpointUUID, toPortUUID, parseEndpointID } from "../flowchart/utils";
import { StatusManager } from "../flowchart/statusmgr";
const search = ref("");
const portSelectShow = ref(false);
const selectedPortID = ref("");
const routePortName = ref("");
const plus = ref(Plus);
const filterTableData = computed(() =>
  tableData.filter(
    (data) =>
      !search.value ||
      data.name.toLowerCase().includes(search.value.toLowerCase())
  )
);
const handleDelete = (index: number) => {
  tableData.splice(index, 1);
};


const endpointDirection = computed(() => {
  return (endpointID: string) => {
    try {
      return parseEndpointID(endpointID).direction
    } catch (error) {
      return "<UNDEFINED>"
    }
  }
})

const endpointOccupied = computed(() => {
  return (endpointID: string): boolean => {
    const statusMgr = props.statusMgr as StatusManager
    const currentEndpoint = parseEndpointID(endpointID)
    // 不得重复绑定
    for (const routePort of tableData) {
      // 已被连接的endpoint
      const connectedEndpointUUID = toPortUUID(routePort.connectedNode, routePort.type, routePort.connectedPort)
      if (endpointID == connectedEndpointUUID) {
        return true
      }
    }
    // 对于输入端口，不能有其他连边。
    if (statusMgr.endpointHasConnection(endpointID) && currentEndpoint.direction == 'input') {
      return true
    }
    return false
  }
})

const portSelected = () => {
  const ep = allEndpoints.value.find(
    (ep: Port) => portToEndpointUUID(ep) == selectedPortID.value
  );
  if (ep == null) {
    throw Error(`ep is null, querying id ${selectedPortID.value}`);
  }
  tableData.push({
    name: routePortName.value,
    type: ep.direction as "input" | "output",
    connectedPort: ep.endpointID,
    connectedNode: ep.nodeID,
  });
};

const tableData: RoutePort[] = reactive<RoutePort[]>([]);

const props = defineProps({
  statusMgr: {
    type: Object,
    required: true,
  },
});
const highlight = (port: RoutePort) => {
  emitHighlightPort(
    toPortUUID(port.connectedNode, port.type, port.connectedPort)
  );
};

const allEndpoints = ref<Port[]>([]);

const setEndpoints = (endpoints: Port[]) => {
  allEndpoints.value = []
  for (const item of endpoints) {
    allEndpoints.value.push(item);
  }
};

const dump = (): RouteSettings => {
  const inPorts: RoutePort[] = tableData.filter(
    (conf: RoutePort) => conf.type == "input"
  );
  const outPorts: RoutePort[] = tableData.filter(
    (conf: RoutePort) => conf.type == "output"
  );
  return {
    inPorts,
    outPorts,
  };
};

const load = (rs: RouteSettings) => {
  tableData.splice(0)
  for (const p of rs.inPorts) {
    tableData.push(p);
  }
  for (const p of rs.outPorts) {
    tableData.push(p);
  }
};

const clear = () => {
  const length = tableData.length;
  for (let i = 0; i < length; i++) {
    tableData.shift();
  }
};

defineExpose({ dump, load, clear, setEndpoints });
</script>
